package com.ymm.lulutong.mq.consumer;

import com.alibaba.fastjson.JSON;
import com.ymm.lulutong.constants.*;
import com.ymm.lulutong.domain.ShipperNoticeDomainService;
import com.ymm.lulutong.domain.ShipperWalletDomainService;
import com.ymm.lulutong.entity.CargoOpsLog;
import com.ymm.lulutong.entity.Notice;
import com.ymm.lulutong.entity.Wallet;
import com.ymm.lulutong.mapper.ShipperCargoOpsLogMapper;
import com.ymm.lulutong.mq.consumer.msg.CargoPullOffMsg;
import com.ymm.lulutong.websocket.WebSocket;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Objects;

/**
 * 货源下架 消息消费者
 *
 * @author guorui
 */
@Slf4j
@Component
@RocketMQMessageListener(topic = "${mq.topic.cargo}", consumerGroup = "${mq.consumer.groupname.cargo.pulloff}", selectorExpression = "pulloff", maxReconsumeTimes = 3)
public class CargoPullOffMsgConsumer implements RocketMQListener<MessageExt> {
    @Resource
    private ShipperCargoOpsLogMapper shipperCargoOpsLogMapper;

    @Resource
    private ShipperWalletDomainService shipperWalletDomainService;

    @Resource
    private WebSocket webSocket;

    @Resource
    private ShipperNoticeDomainService shipperNoticeDomainService;

    @Override
    public void onMessage(MessageExt messageExt) {
        //解析消息内容
        String body = new String(messageExt.getBody(), StandardCharsets.UTF_8);
        CargoPullOffMsg cargoPullOffMsg = JSON.parseObject(body, CargoPullOffMsg.class);
        if (Objects.isNull(cargoPullOffMsg)) {
            log.info("cargoPullOffMsg为空！");
            return;
        }
        Long shipperId = cargoPullOffMsg.getShipperId();
        Long cargoId = cargoPullOffMsg.getCargoId();
        Long orderId = cargoPullOffMsg.getOrderId();
        Integer cargoPrice = cargoPullOffMsg.getCargoPrice();

        Integer opsType = CargoOpsEnum.PULLOFF.getCode();
        if (Objects.isNull(cargoId) || Objects.isNull(shipperId) || Objects.isNull(cargoPrice)) {
            log.info("参数为空！");
            return;
        }
        CargoOpsLog cargoOpsLog = new CargoOpsLog();
        cargoOpsLog.setShipperId(shipperId);
        cargoOpsLog.setCargoId(cargoId);
        cargoOpsLog.setOrderId(orderId);
        cargoOpsLog.setOpsType(opsType);
        cargoOpsLog.setOpsPersonType(cargoPullOffMsg.getOpsPersonType());
        cargoOpsLog.setOpsPersonId(cargoPullOffMsg.getOpsPersonId());
        cargoOpsLog.setCreateTime(new Date());
        cargoOpsLog.setUpdateTime(new Date());
        cargoOpsLog.setExecutionStatus(MessgeStatusEnum.IN_EXECUTION.getCode());

        //保存到数据库
        try {
            shipperCargoOpsLogMapper.add(cargoOpsLog);
        } catch (Exception e) {
            if (!Objects.isNull(shipperCargoOpsLogMapper.getLogIdByShipperIdAndCargoIdAndOpsType(shipperId, cargoId, opsType))) {
                log.info(cargoOpsLog.getLogId() + "消息已经被消费过");
                return;
            } else {
                log.info("数据库错误");
                //重试
                throw e;
            }
        }

        //退钱
        try {
            shipperWalletDomainService.refund(shipperId, cargoPullOffMsg.getCargoPrice(), cargoId, orderId);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("退钱失败，重试");
            // 重试
            shipperCargoOpsLogMapper.deleteByLogId(cargoOpsLog.getLogId());
            throw new RuntimeException(e);
        }
        //投递通知
        try {
            Notice notice = new Notice();
            notice.setShipperId(shipperId);
            if (cargoPullOffMsg.getOpsPersonType().equals(OpsPersonTypeEnum.SYSTEM.getCode())){
                notice.setContent("由于您的货超过发货时间24小时未接单，被系统自动下架！");
            } else if (cargoPullOffMsg.getOpsPersonType().equals(OpsPersonTypeEnum.AGENT.getCode())){
                notice.setContent("您的货已由客服下架！");
            } else if (cargoPullOffMsg.getOpsPersonType().equals(OpsPersonTypeEnum.SHIPPER.getCode())){
                notice.setContent("下架货源成功！");
            }
            notice.setFromPersonType(NoticeFromPersonEnum.SYSTEM.getCode());
            notice.setFromPersonId(0L);
            notice.setNoticeType(NoticeTypeEnum.CARGO_NOTICE.getCode());
            if (Objects.isNull(orderId)) {
                notice.setAdditionalInformation("{\"cargoId\":" + cargoId + "}");
            } else {
                notice.setAdditionalInformation("{\"orderId\":" + orderId + ", \"cargoId\":" + cargoId + "}");
            }
            shipperNoticeDomainService.saveNotice(notice);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //WebSocket通知
        try {
            String content = null;
            if (cargoPullOffMsg.getOpsPersonType().equals(OpsPersonTypeEnum.SYSTEM.getCode())) {
                content = "由于您的货超过发货时间24小时未接单，被系统自动下架！";
            } else if (cargoPullOffMsg.getOpsPersonType().equals(OpsPersonTypeEnum.AGENT.getCode())) {
                content = "您的货已由客服下架！";
            } else if (cargoPullOffMsg.getOpsPersonType().equals(OpsPersonTypeEnum.SHIPPER.getCode())) {
                content = "下架货源成功！";
            }
            webSocket.sendOnMessage(shipperId, content);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //设置业务执行状态为完成
        shipperCargoOpsLogMapper.updateExecutionStatusByLogId(cargoOpsLog.getLogId(), MessgeStatusEnum.COMPLETED.getCode());
    }


}
